home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UArticleTextCache.cp < prev    next >
Encoding:
Text File  |  1994-02-20  |  5.9 KB  |  242 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UArticleTextCache.cp
  3.  
  4. #include "UArticleTextCache.h"
  5. #include "UNntp.h"
  6. #include "UGroupDoc.h"
  7. #include "UPrefsDatabase.h"
  8. #include "Tools.h"
  9.  
  10. #include <RsrcGlobals.h>
  11. #include <Folders.h>
  12.  
  13. #pragma segment MyArticle
  14.  
  15. #define qDebugCache qDebug & 0
  16. #define qDebugCacheIntense qDebug & 0
  17.  
  18. PArticleTextCache *gArticleTextCache = nil;
  19.  
  20. //------------------------------------------------------
  21. ArticleEntry::ArticleEntry()
  22. {
  23. }
  24.  
  25. //------------------------------------------------------
  26. PArticleTextCache::PArticleTextCache()
  27. {
  28. //    inherited::Initialize();
  29.     fInIndex = 0;
  30.     fOutIndex = fInIndex + 1;
  31.     fLastUsedIndex = 0;
  32.     fNoUsedEntries = 0;
  33.     fSumSize = 0;
  34.     for (short i = 0; i < kMaxNoCachedArticleTexts; i++)
  35.     {
  36.         fArticleTable[i].fID = -1;
  37.         fArticleTable[i].fH = nil;
  38.         fArticleTable[i].fSize = 0;
  39.     }
  40. }
  41.  
  42. void PArticleTextCache::IArticleTextCache()
  43. {
  44. //    inherited::IObject();
  45. }
  46.  
  47. PArticleTextCache::~PArticleTextCache()
  48. {
  49.     for (short i = 0; i < kMaxNoCachedArticleTexts; i++)
  50.     {
  51.         DisposeIfHandle(fArticleTable[i].fH);
  52.     }
  53. //    inherited::Free();
  54. }
  55.  
  56. inline void GoNextEntry(short &index)
  57.     if (index == kMaxNoCachedArticleTexts - 1)
  58.         index = 0;
  59.     else
  60.         index++;
  61. }
  62.  
  63. inline void GoPrevEntry(short &index)
  64. {
  65.     if (index)
  66.         index--;
  67.     else
  68.         index = kMaxNoCachedArticleTexts - 1;
  69. }
  70.  
  71. void PArticleTextCache::FlushOneArticle()
  72. {
  73.     ArticleEntryPtr aeP = fArticleTable + fOutIndex;
  74. #if qDebug
  75. //    Boolean prevLock = Lock(true);
  76. #if qDebugCache
  77.     fprintf(stderr, "PArticleTextCache: Flushing, id = %ld, size = %ld, handle = %lx, fSumSize = %ld\n", aeP->fID, aeP->fSize, aeP->fH, fSumSize);
  78. #endif
  79.     if (!IsHandle(aeP->fH))
  80.     {
  81.         ProgramBreak("The article handle is not valid (flushing)\n");
  82.         aeP->fH = nil;
  83.     }
  84. //    Lock(prevLock);
  85. #endif
  86.     Handle h = aeP->fH;  // wait with m-mgr until done with Pointer
  87.     aeP->fH = nil;
  88.     fSumSize -= aeP->fSize;
  89.     aeP->fSize = 0;
  90.     aeP->fID = -1;
  91.     if (h)
  92.         DisposeHandle(h);
  93.     fNoUsedEntries--;
  94.     GoNextEntry(fOutIndex);
  95.     fLastUsedIndex = fInIndex;
  96. }
  97.  
  98. void PArticleTextCache::FlushToFit(const long maxSumSize)
  99. {
  100.     while (fSumSize > maxSumSize || fNoUsedEntries >= kMaxNoCachedArticleTexts)
  101.     {
  102.         FlushOneArticle();
  103.     } // while
  104. }
  105.  
  106. Handle PArticleTextCache::GetArticleFromNntp(const CStr255 &groupDotName, long id)
  107. {
  108.     FlushToFit(gPrefs->GetLongPrefs('AMem'));
  109.     PNntp *nntp = gNntpCache->GetNntp();
  110.     Handle h = nil;
  111.     FailInfo fi;
  112.     if (fi.Try())
  113.     {
  114.         nntp->SetGroup(groupDotName);
  115.         h = nntp->GetArticle(id);
  116.         fi.Success();
  117.     }
  118.     else // fail
  119.     {
  120.         gNntpCache->DiscardNntp(nntp);
  121.         fi.ReSignal();
  122.     }
  123.     gNntpCache->ReturnNntp(nntp); nntp = nil;
  124. #if qDebug
  125.     if (!h)
  126.         ProgramBreak("PNntp returned _NIL_ article handle to PArticleTextCache");
  127. #endif
  128.     GoNextEntry(fInIndex);
  129.     if (!fNoUsedEntries)
  130.     {
  131. #if qDebug
  132.         if (fInIndex != fOutIndex)
  133.             ProgramBreak("misalign between fInIndex and fOutIndex");
  134. #endif
  135.         fOutIndex = fInIndex;
  136.     }
  137.     fNoUsedEntries++;
  138. #if qDebugCacheIntense
  139.     fprintf(stderr, "PArticleTextCache, got article group = %s, ID = %ld from nntp\n", (char*)groupDotName, id);
  140.     fprintf(stderr, "-   put in cache with index = %ld, size = %ld\n", fInIndex, GetHandleSize(h));
  141. #endif
  142.     fArticleTable[fInIndex].fID = id;
  143.     fArticleTable[fInIndex].fGroupDotName = groupDotName;
  144.     fArticleTable[fInIndex].fH = h;
  145.     long size = GetHandleSize(h);
  146.     fSumSize += size;
  147.     fArticleTable[fInIndex].fSize = size;
  148.     fLastUsedIndex = fInIndex;
  149. #if qDebug
  150.         ArticleEntryPtr aeP = fArticleTable + fInIndex;
  151. //        Boolean prevLock = Lock(true);
  152. #if qDebugCache
  153.         fprintf(stderr, "PArticleTextCache: new article id = %ld, size = %ld, handle = 0x%lx\n", aeP->fID, aeP->fSize, aeP->fH);
  154. #endif
  155.         if (!IsHandle(aeP->fH))
  156.             ProgramBreak("The article handle is not valid (obtained from nntp)\n");
  157. //        Lock(prevLock);
  158. #endif
  159.     return h;
  160. }
  161.  
  162. Handle PArticleTextCache::GetArticleText(const CStr255 &groupDotName, long id)
  163. {
  164. #if qDebugCacheIntense
  165.     fprintf(stderr, "PArticleTextCache::GetArticle, group = %s, ID = %ld\n", (char*)groupDotName, id);
  166. #endif
  167.     // was it the last one?
  168.     if (fNoUsedEntries && id == fArticleTable[fLastUsedIndex].fID && groupDotName == fArticleTable[fLastUsedIndex].fGroupDotName)
  169.     {
  170. #if qDebugCacheIntense
  171.         fprintf(stderr, "-  found article as last used with index = %ld\n", fLastUsedIndex);
  172. #endif
  173.         return fArticleTable[fLastUsedIndex].fH;
  174.     }
  175.     // else try go seek for it
  176.     short index = fInIndex;
  177.     for (short i = 1; i <= kMaxNoCachedArticleTexts; i++)
  178.     {
  179.         if (id == fArticleTable[index].fID && groupDotName == fArticleTable[index].fGroupDotName)
  180.         {
  181. #if qDebugCacheIntense
  182.             fprintf(stderr, "-  found article with index = %ld, fLastUsedIndex = %ld\n", i, fLastUsedIndex);
  183. #endif
  184.             fLastUsedIndex = index;
  185.             return fArticleTable[index].fH; // found it
  186.         }
  187.         GoPrevEntry(index);
  188.     }
  189. #if qDebugCacheIntense
  190.     fprintf(stderr, "-  did not find article, fetches it from nntp\n");
  191. #endif
  192.     return GetArticleFromNntp(groupDotName, id);
  193. }
  194.  
  195. void PArticleTextCache::FlushCache()
  196. {
  197.     while (fNoUsedEntries)
  198.         FlushOneArticle();
  199. }
  200.  
  201. void InitUArticleTextCache()
  202. {
  203. #if qDebug
  204.     if (gArticleTextCache)
  205.         ProgramBreak("InitUArticleTextCache is called twice");
  206. #endif
  207.     PArticleTextCache *ac = new PArticleTextCache();
  208.     ac->IArticleTextCache();
  209.     gArticleTextCache = ac;
  210. }
  211.  
  212. void CloseDownUArticleTextCache()
  213. {
  214. #if qDebug
  215.     if (!gArticleTextCache)
  216.         fprintf(stderr, "gArticleTextCache is nil in CloseDownUArticleTextCache\n");
  217. #endif
  218.     FreeIfPtrObject(gArticleTextCache);     gArticleTextCache = nil;
  219. }
  220.  
  221. void PArticleTextCache::DebugDump()
  222. {
  223. #if qDebug
  224.     fprintf(stderr, "Debug dump of article text cache:\n");
  225.     short index = fInIndex;
  226.     for (short i = 1; i <= kMaxNoCachedArticleTexts; i++)
  227.     {
  228.         ArticleEntry entry;
  229.         BytesMove(fArticleTable + index, &entry, sizeof(entry));
  230.         if (entry.fID >= 0)
  231.         {
  232.             fprintf(stderr, "   index = %ld, group = %s, ID = %ld, size = %ld, handle = $%lx\n",
  233.                 i, (char*)entry.fGroupDotName, entry.fID, entry.fSize, entry.fH);
  234.             if (!IsHandle(entry.fH))
  235.                 fprintf(stderr, "    *** This handle is not valid\n");
  236.         }
  237.         GoPrevEntry(index);
  238.     }
  239. #endif
  240. }
  241.